home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / General / GCC 1.37.1r15 / Machines / out-convex.c < prev    next >
Text File  |  1990-03-14  |  5KB  |  238 lines

  1. /* Subroutines for insn-output.c for Convex.
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  *  set_cmp (left_rtx, right_rtx, [bhwlsd])
  22.  *  gen_cmp (label_rtx, cmpop, [tf])
  23.  *
  24.  *  set_cmp saves the operands of a "cmp" insn,
  25.  *    along with the type character to be used in the compare instruction.
  26.  *
  27.  *  gen_cmp finds out what comparison is to be performed and
  28.  *    outputs the necessary instructions, eg,
  29.  *    "eq.w a1,a2 ! jbra.t L5"
  30.  *    for (cmpsi a1 a2) (beq L5)
  31.  */
  32.  
  33. static rtx xop0, xop1;
  34. static char typech, regch;
  35.  
  36. char *
  37. set_cmp (op0, op1, typechr)
  38.      rtx op0, op1;
  39.      char typechr;
  40. {
  41.   xop0 = op0;
  42.   xop1 = op1;
  43.   typech = typechr;
  44.   if (GET_CODE (op0) == REG)
  45.     regch = REGNO_OK_FOR_BASE_P (REGNO (op0)) ? 'a' : 's';
  46.   else if (GET_CODE (op1) == REG)
  47.     regch = REGNO_OK_FOR_BASE_P (REGNO (op1)) ? 'a' : 's';
  48.   else abort ();
  49.   return "";
  50. }
  51.  
  52. char *
  53. gen_cmp (label, cmpop, tf)
  54.      rtx label;
  55.      char *cmpop;
  56.      char tf;
  57. {
  58.   char buf[80];
  59.   char revop[4];
  60.   rtx ops[3];
  61.  
  62.   ops[2] = label;
  63.  
  64.   /* constant must be first; swap operands if necessary
  65.      if lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
  66.      and reverse the sense of the jump */
  67.  
  68.   if (CONSTANT_P (xop1) || GET_CODE (xop1) == CONST_DOUBLE)
  69.     {
  70.       ops[0] = xop1;
  71.       ops[1] = xop0;
  72.       if (cmpop[0] == 'l')
  73.     {
  74.       bcopy (cmpop, revop, 4);
  75.       revop[1] ^= 'e' ^ 't';
  76.       tf ^= 't' ^ 'f';
  77.       cmpop = revop;
  78.     }
  79.     }
  80.   else
  81.     {
  82.       ops[0] = xop0;
  83.       ops[1] = xop1;
  84.     }
  85.  
  86.   sprintf (buf, "%s.%c %%0,%%1\n\tjbr%c.%c %%l2", cmpop, typech, regch, tf);
  87.   output_asm_insn (buf, ops);
  88.   return "";
  89. }
  90.  
  91. /*
  92.  *  pick target machine if not specified, the same as the host
  93.  */
  94.  
  95. extern int target_flags;
  96.  
  97. override_options ()
  98. {
  99. #ifdef convex
  100. #include <sys/sysinfo.h>    
  101.   if (! (TARGET_C1 || TARGET_C2))
  102.     {
  103.       struct system_information sysinfo;
  104.       getsysinfo (sizeof sysinfo, &sysinfo);
  105.       if (sysinfo.cpu_type >= SI_CPUTYPE_C2MP)
  106.     target_flags |= 2;
  107.       else
  108.     target_flags |= 1;
  109.     }
  110. #endif
  111. }
  112.  
  113. /*
  114.  * Routines to look at CONST_DOUBLEs without sinful knowledge of
  115.  * what the inside of u.d looks like
  116.  *
  117.  * const_double_high_int  -- high word of machine double or long long
  118.  * const_double_low_int   -- low word
  119.  * const_double_float_int -- the word of a machine float
  120.  */
  121.  
  122. static double frexp ();
  123. static void float_extract ();
  124.  
  125. int
  126. const_double_high_int (x)
  127.      rtx x;
  128. {
  129.   if (GET_MODE (x) == DImode)
  130.     return CONST_DOUBLE_HIGH (x);
  131.   else
  132.     {
  133.       int sign, expd, expf;
  134.       unsigned fracdh, fracdl, fracf;
  135.       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  136.  
  137.       if (fracdh == 0)
  138.     return 0;
  139.       if (expd < -01777 || expd > 01777)
  140.     return 1 << 31;
  141.       return sign << 31 | (expd + 02000) << 20 | fracdh - (1 << 20);
  142.     }
  143. }
  144.  
  145. int
  146. const_double_low_int (x)
  147.      rtx x;
  148. {
  149.   if (GET_MODE (x) == DImode)
  150.     return CONST_DOUBLE_LOW (x);
  151.   else
  152.     {
  153.       int sign, expd, expf;
  154.       unsigned fracdh, fracdl, fracf;
  155.       float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  156.       return fracdl;
  157.     }
  158. }
  159.  
  160. int
  161. const_double_float_int (x)
  162.      rtx x;
  163. {
  164.   int sign, expd, expf;
  165.   unsigned fracdh, fracdl, fracf;
  166.   float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
  167.  
  168.   if (fracf == 0)
  169.     return 0;
  170.   if (expf < -0177 || expf > 0177)
  171.     return 1 << 31;
  172.   return sign << 31 | (expf + 0200) << 20 | fracf - (1 << 23);
  173. }
  174.  
  175. #define T21  ((double) (1 << 21))
  176. #define T24  ((double) (1 << 24))
  177. #define T53  ((double) (1 << 27) * (double) (1 << 26))
  178.  
  179. static void
  180. float_extract (x, sign, expd, fracdh, fracdl, expf, fracf)
  181.      rtx x;
  182.      int *sign, *expd, *expf;
  183.      unsigned *fracdh, *fracdl, *fracf;
  184. {
  185.   int exp, round;
  186.   double d, r;
  187.   union real_extract u;
  188.  
  189.   bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
  190.  
  191.   /* Get sign and exponent.  */
  192.  
  193.   if (*sign = u.d < 0)
  194.     u.d = -u.d;
  195.   d = frexp (u.d, &exp);  
  196.  
  197.   /* Get 21 fraction bits for high word and 32 for low word.  */
  198.  
  199.   for (round = 0; ; round = 1)
  200.     {
  201.       r = frexp (round ? d + 1.0 / T53 : d, expd);
  202.       *expd += exp;
  203.       *fracdh = r * T21;
  204.       *fracdl = (r - *fracdh / T21) * T53;
  205.       if (round || ((r - *fracdh / T21) - *fracdl / T53) < 0.5 * T53)
  206.     break;
  207.     }
  208.  
  209.   /* Get 24 bits for float fraction. */
  210.  
  211.   for (round = 0; ; round = 1)
  212.     {
  213.       r = frexp (round ? d + 1.0 / T24 : d, expf);
  214.       *expf += exp;
  215.       *fracf = r * T24;
  216.       if (round || (r - *fracf / T24) < 0.5 * T24)
  217.     break;
  218.     }
  219. }
  220.  
  221. static double
  222. frexp (d, exp)
  223.      double d;
  224.      int *exp;
  225. {
  226.   int e = 0;
  227.  
  228.   if (d > 0)
  229.     {
  230.       while (d < 0.5) d *= 2.0, e--;
  231.       while (d >= 1.0) d /= 2.0, e++;
  232.     }
  233.  
  234.   *exp = e;
  235.   return d;
  236. }
  237.  
  238.